﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AgCIM.Tools.Maths.Numerics;

namespace AgCIMProductFuncLib
{
    public class AgCIMProducts
    {
        public TitleClass title { get; set; }
        public int animationDurationUpdate { get; set; } = 1500;

        public string animationEasingUpdate { get; set; } = "quinticInOut";
        public List<SeriesClass> series {  get; set; }

        internal void CreateCellLines(BoundingBox globalBoundingBox)
        {
            SeriesClass lineSeries = series[0];
            lineSeries.FromCellLines(globalBoundingBox);
        }

        internal void FromProducts(List<ProductLine> products)
        {
            title = new TitleClass() { text = "AgCIM 产品线与产品功能" };
            series = new List<SeriesClass>();
            SeriesClass lineSeries = new SeriesClass()
            {
                data = new List<nodeClass>(),
                links = new List<linkItem>(),
                label=new StyleClass() { normal=new normalClass()
                {
                     position= "right"
                } }
            };
            series.Add(lineSeries);
           
            lineSeries.FromLines(products);
            lineSeries.FromPoints(products);
            lineSeries.FromProduct(products);
        }
    }
    public class TitleClass
    {
        public string text;
    }
    public class SeriesClass
    {
        public string type { get; set; } = "graph";
        public string layout { get; set; } = "none";
        public int symbolSize { get; set; } = 16;
        public bool roam { get; set; } = true;
        public StyleClass itemStyle { get; set; }
        public StyleClass label { get; set; }
        public StyleClass lineStyle { get; set; }
        public List<nodeClass> data { get; set; }
        public List<linkItem> links { get; set; }

        private HashSet<string> m_nodeNames=new HashSet<string>();
        
        internal void FromLines(List<ProductLine> products)
        {
            itemStyle = new StyleClass()
            {
                normal = new normalClass()
                {
                    color = "#FFFFFF",
                    borderColor = "#009900",
                    show = true
                }
            };
            label = new StyleClass()
            {
                normal = new normalClass()
                {
                    color = "#C9C9C9",
                    show = false,
                    position = "right",
                    fontSize = 12
                }
            };
            lineStyle = new StyleClass()
            {
                normal = new normalClass()
                {
                    width = 2,
                    color = "#009900"
                }
            };

            List<string> colorRamps = new List<string>() {
    "#e3002b",  // 红色 - 1号线
    "#009933",  // 绿色 - 2号线
    "#ffcc00",  // 黄色 - 3号线
    "#663399",  // 紫色 - 4号线
    "#ff6600",  // 橙色 - 5号线
    "#990099",  // 深紫色 - 6号线
    "#ff9900",  // 深橙色 - 7号线
    "#0066cc",  // 蓝色 - 8号线
    "#00ccff",  // 浅蓝色 - 9号线
    "#cc0066",  // 玫红色 - 10号线
    "#66cc00",  // 浅绿色 - 11号线
    "#9966cc",  // 淡紫色 - 12号线
    "#ff3366",  // 粉红色 - 13号线
    "#33cc99",  // 青绿色 - 14号线
    "#ffcc99",  // 浅橙色 - 15号线
    "#99ccff",  // 天蓝色 - 16号线
    "#ff9966",  // 橙黄色 - 17号线
    "#cc9933",  // 棕黄色 - 18号线
    "#cccccc",  // 浅灰色 - 19号线
    "#666666"   // 深灰色 - 20号线
};
            int colorIndex = 0;
            Dictionary<string, string> appColor = new Dictionary<string, string>();

            for (var i = 0; i < products.Count; i++)
            {
                for (var j = 0; products[i].Lines != null && j < products[i].Lines.Count; j++)
                {
                    var line = products[i].Lines[j];
                    var lineColor = colorRamps[colorIndex];
                    var appId = products[i].ProductName + "_" + line.AppID;
                    if (appColor.ContainsKey(appId))
                    {
                        lineColor = appColor[appId];
                    }
                    else
                    {
                        colorIndex++;
                        colorIndex = colorIndex % colorRamps.Count;
                        appColor[appId] = lineColor;
                    }
                    for (var k = 0; k < line.Parts.Count; k++)
                    {
                        var part = line.Parts[k];
                        for (var m = 0; m < part.Count; m++)
                        {
                            var node = new nodeClass()
                            {
                                name = i + "-" + j + "-" + k + "-" + m,
                                x = part[m].X,
                                y = part[m].Y,
                                symbolSize = 0,
                                label = new StyleClass() { normal = new normalClass() { show = false } }
                            };
                            data.Add(node);
                            AddNodeName(node);
                        }
                        for (var m = 0; m < part.Count - 1; m++)
                        {
                            var link = new linkItem()
                            {
                                source = i + "-" + j + "-" + k + "-" + m,
                                target = i + "-" + j + "-" + k + "-" + (m + 1),
                                lineStyle = new StyleClass()
                                {
                                    normal = new normalClass()
                                    {
                                        color = lineColor,
                                        borderColor = "#FF0000",
                                    }
                                }
                            };
                            links.Add(link);
                        }
                    }
                }
            }
        }

        internal void FromCellLines(BoundingBox globalBoundingBox)
        {
            double startX = Math.Ceiling(globalBoundingBox.MinX / 0.15) * 0.15;
            double startY = Math.Ceiling(globalBoundingBox.MinY / 0.15) * 0.15;
            int cellColumnCount = 0;
            int cllRowCount = 0;
            var dx = 5000 / globalBoundingBox.Width;
            for (var j = startX; j < globalBoundingBox.MaxX; j+=0.15)
            {
                cellColumnCount++;
                cllRowCount = 0;
                for (var k = startY; k < globalBoundingBox.MaxY; k+=0.15)
                {
                    cllRowCount++;
                    var p=new Coordinate() { X=j,Y=k };
                    p.ScaleToWidth(globalBoundingBox.MinX, globalBoundingBox.MaxY, dx);
                    var node = new nodeClass()
                    {
                        name = "Cell"+ cllRowCount + "_"+ cellColumnCount,
                        x = p.X,
                        y = p.Y,
                        symbolSize = 0,
                        label = new StyleClass() { normal = new normalClass() { show = false } }
                    };
                    AddNodeName(node);
                    data.Add(node);
                }
            }
            for (var m = 0; m < cllRowCount;m++)
            {
                var link = new linkItem()
                {
                    source = "Cell" + (m + 1) + "_" + 1,
                    target = "Cell" + (m + 1) + "_" + cellColumnCount,
                    lineStyle = new StyleClass()
                    {
                        normal = new normalClass()
                        {
                            color = "#AAAAAA",
                            borderColor = "#FF0000",
                            width = 0.5
                        }
                    }
                };
                links.Add(link);

            }
            for (var m = 0; m < cellColumnCount; m++)
            {
                var link = new linkItem()
                {
                    source = "Cell" + 1 + "_" + (m+1),
                    target = "Cell" + cllRowCount + "_" + (m + 1),
                    lineStyle = new StyleClass()
                    {
                        normal = new normalClass()
                        {
                            color = "#AAAAAA",
                            borderColor = "#FF0000",
                            width = 0.5
                        }
                    }
                };
                links.Add(link);

            }
        }

        internal void FromPoints(List<ProductLine> products)
        {
            itemStyle = new StyleClass() { normal = new normalClass() { color = "#FFFFFF", borderColor = "#009900" } };
            label = new StyleClass()
            {
                normal = new normalClass() { color = "#C9C9C9", show = true, position = "buttom", fontSize = 12 }
            };
            lineStyle = new StyleClass()
            {
                normal = new normalClass() { width = 3, color = "#009900" }
            };

            for (var i = 0; i < products.Count; i++)
            {
                for (var j = 0; products[i].PointLayer != null && j < products[i].PointLayer.Count; j++)
                {
                    var point = products[i].PointLayer[j];
                    var node = new nodeClass()
                    {
                        name = point.Attributes["Version"] + " " + point.Attributes["Name"],
                        x = point.Point.X,
                        y = point.Point.Y,
                        symbolSize =6,
                        itemStyle = new StyleClass()
                        {
                            normal = new normalClass()
                            {
                                color = "#F0C209",
                            }
                        },
                        label = new StyleClass()
                        {
                            normal = new normalClass()
                            {
                                color = "#000000",
                            }
                        }
                    };
                    AddNodeName(node);
                    data.Add(node);
                }
            }
        }
        internal void FromProduct(List<ProductLine> products)
        {
            itemStyle = new StyleClass() { normal = new normalClass() { color = "#FFFFFF", borderColor = "#009900" } };
            label = new StyleClass()
            {
                normal = new normalClass() { color = "#C9C9C9", show = true, position = "buttom", fontSize = 12 }
            };
            lineStyle = new StyleClass()
            {
                normal = new normalClass() { width = 3, color = "#009900" }
            };

            for (var i = 0; i < products.Count; i++)
            {
                Dictionary<string,int> prodocutCount= new Dictionary<string,int>();
                for (var j = 0; products[i].ProductLayer != null && j < products[i].ProductLayer.Count; j++)
                {
                    var point = products[i].ProductLayer[j];
                    var pn = point.Attributes["Name"].ToString();
                    int t = prodocutCount.ContainsKey(pn) ? (prodocutCount[pn] + 1) : 0;
                    if (t == 0)
                    {
                        prodocutCount.Add(pn, 1);
                    }
                    var node = new nodeClass()
                    {
                        name = point.Attributes["Name"]+"".PadRight(t,' '),
                        x = point.Point.X,
                        y = point.Point.Y,
                        symbol= "image://data:",
                        symbolSize = 8,
                        itemStyle = new StyleClass()
                        {
                            normal = new normalClass()
                            {
                                color = "#F0C209",
                            }
                        },
                        label = new StyleClass()
                        {
                            normal = new normalClass()
                            {
                                color = "#000000",
                            }
                        }
                    };
                    data.Add(node);
                }
            }
        }

        private void AddNodeName(nodeClass node)
        {
            if (m_nodeNames.Contains(node.name))
            {
                throw new Exception(node.name+"重复");
            }
            m_nodeNames.Add(node.name);
        }
    }
    public class StyleClass
    {
        public normalClass normal { get; set; }
    }
    public class normalClass
    {
        public bool show { get; set; } = true;
        public string color { get; set; } = "#FFFFFF";//颜色默认白色
        public string borderColor { get; set; } = "#009900";//边框默认绿色
        public string position { get; set; } = "right";//下方显示;
        public int fontSize { get; set; } = 12;//字体样式
        public double width { get; set; } = 3;
    }
    public class nodeClass
    {
        public string name { get; set; } = "助理研究员";
        public double x { get; set; } = 0;
        public double y { get; set; } = 0;
        public StyleClass itemStyle { get; set; }
        public StyleClass label { get; set; }
        public double symbolSize { get; set; }
        public string symbol { get; set; }
    }
    public class linkItem
    {
        public string source { get; set; }
        public string target { get; set; }
        public StyleClass lineStyle { get; set; }
    }
}
